package com.zzh.zzhaiagent.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.zzh.zzhaiagent.domain.vo.UserProfilesVO;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Redis 与 Hutool Hash 工具类
 * 用于将对象以 Hash 形式存储到 Redis
 */
@Component
public class RedisHutoolHashUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 将 UserProfilesVO 对象以 Hash 形式存储到 Redis
     * @param key Redis 键
     * @param userProfilesVO 用户信息对象
     * @param timeout 超时时间（单位：秒）
     */
    public void setUserProfiles(String key, UserProfilesVO userProfilesVO, long timeout) {
        if (StrUtil.isBlank(key) || userProfilesVO == null) {
            return;
        }
        
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        
        // 将对象转换为 Map
        Map<String, Object> userMap = BeanUtil.beanToMap(userProfilesVO, false, true);
        
        // 处理 LocalDateTime 类型（需要序列化为字符串）
        if (userMap.containsKey("createTime") && userMap.get("createTime") != null) {
            userMap.put("createTime", userMap.get("createTime").toString());
        }
        if (userMap.containsKey("updateTime") && userMap.get("updateTime") != null) {
            userMap.put("updateTime", userMap.get("updateTime").toString());
        }
        
        // 存储到 Redis
        hashOps.putAll(key, userMap);
        redisTemplate.expire(key, timeout, TimeUnit.HOURS);//缓存用户信息2h
    }

    /**
     * 从 Redis 获取 Hash 并反序列化为 UserProfilesVO 对象
     * @param key Redis 键
     * @return UserProfilesVO 对象
     */
    public UserProfilesVO getUserProfiles(String key) {
        if (StrUtil.isBlank(key)) {
            return null;
        }
        
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        Map<String, Object> userMap = hashOps.entries(key);
        
        if (CollUtil.isEmpty(userMap)) {
            return null;
        }
        
        // 处理 LocalDateTime 类型（需要从字符串反序列化为对象）
        if (userMap.containsKey("createTime") && userMap.get("createTime") != null) {
            userMap.put("createTime", LocalDateTime.parse(userMap.get("createTime").toString()));
        }
        if (userMap.containsKey("updateTime") && userMap.get("updateTime") != null) {
            userMap.put("updateTime", LocalDateTime.parse(userMap.get("updateTime").toString()));
        }
        
        // 将 Map 转换为对象
        return BeanUtil.mapToBean(userMap, UserProfilesVO.class, true);
    }

    /**
     * 更新 Redis 中 Hash 的某个字段
     * @param key Redis 键
     * @param field Hash 字段名
     * @param value 字段值
     */
    public void updateUserField(String key, String field, Object value) {
        if (StrUtil.isBlank(key) || StrUtil.isBlank(field) || value == null) {
            return;
        }
        
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        hashOps.put(key, field, value);
    }

    /**
     * 批量更新 Redis 中 Hash 的多个字段
     * @param key Redis 键
     * @param fields 字段 Map
     */
    public void updateUserFields(String key, Map<String, Object> fields) {
        if (StrUtil.isBlank(key) || CollUtil.isEmpty(fields)) {
            return;
        }
        
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        hashOps.putAll(key, fields);
        
        // 更新 updateTime 字段
        hashOps.put(key, "updateTime", LocalDateTime.now().toString());
    }

    /**
     * 获取 Redis 中 Hash 的某个字段值
     * @param key Redis 键
     * @param field Hash 字段名
     * @return 字段值
     */
    public Object getUserField(String key, String field) {
        if (StrUtil.isBlank(key) || StrUtil.isBlank(field)) {
            return null;
        }
        
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        return hashOps.get(key, field);
    }

    /**
     * 删除 Redis 中的用户信息
     * @param key Redis 键
     */
    public void deleteUserProfiles(String key) {
        if (StrUtil.isBlank(key)) {
            return;
        }
        redisTemplate.delete(key);
    }

    /**
     * 从 Redis 获取 Hash 并反序列化为 UserProfilesVO 对象，同时刷新过期时间
     * @param key Redis 键
     * @param timeout 超时时间（单位：秒）
     * @return UserProfilesVO 对象
     */
    public UserProfilesVO getUserProfilesAndRefresh(String key, long timeout) {
        UserProfilesVO userProfilesVO = getUserProfiles(key);
        if (userProfilesVO != null) {
            redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
        }
        return userProfilesVO;
    }
}